package jeconbond.experiment.market.resourcerelations.generate;

import java.util.Map;

import jeconbond.automata.INode;
import jeconbond.automata.behaviour.MarketAuditWalkStrategy;
import jeconbond.economic.agent.AutomataAgent;
import jeconbond.economic.market.strategy.IPerformPriceStrategy;
import jeconbond.economic.market.strategy.ObserveCostsProfitMerchantDecorator;
import jeconbond.economic.market.strategy.ProductNecessityMerchant;
import jeconbond.economic.resources.IResourceType;
import jeconbond.economic.resources.ResourceUtils;
import jeconbond.economic.systems.market.IMarketResourceRedestributionSystem;
import jeconbond.economic.systems.market.IMoneyAccount;
import jeconbond.economic.systems.market.MoneyAccount;
import jeconbond.experiment.market.equilibrium.process.MooreExperimentContext;
import jeconbond.experiment.market.resourcerelations.BrosnenExperimentSettings;
import jeconbond.experiment.generate.IAgentsCreator;
import laboratoryQ.experiment.process.IExperimentContext;

public class AuditFlowProdAgentsCreator implements IAgentsCreator {
	static { System.out.println("\nBLOCKING structure of context, sett, gen"); }

	@Override
	public AutomataAgent[] automata2agents(INode[] automatas, IExperimentContext commExperimentContext) {
		int n = automatas.length;
		AutomataAgent[] agents = new AutomataAgent[n];
		MooreExperimentContext experimentContext = 
			(MooreExperimentContext) commExperimentContext;
		BrosnenExperimentSettings settings = 
			(BrosnenExperimentSettings) experimentContext.getExperimentSettings();
		IMarketResourceRedestributionSystem mrrs = experimentContext.getRRS(); 
		Map<IResourceType, double[]> concurrentPrices = 
			experimentContext.getConcurrentPricesMap();
		for (int i = 0; i < n; i++) {
			INode root = automatas[i];
			AutomataAgent agent = new AutomataAgent(root);
			agent.setWalkingListener(experimentContext.getAutomataWalkListener());
			MarketAuditWalkStrategy auditStrat = new MarketAuditWalkStrategy(
					root,
					agent.getInputRS(),
					agent.getOutputRS(),
					mrrs
			);
			IMoneyAccount agentMoney = new MoneyAccount(settings.initMoney);
			ObserveCostsProfitMerchantDecorator observeCPMerch = 
				new ObserveCostsProfitMerchantDecorator(
					agent,
					auditStrat,
					mrrs,
					agentMoney,
					settings.observeCostsTraceLength,
					1.0
			);
			experimentContext.addServiceAgent(observeCPMerch);
			IPerformPriceStrategy performPriceStrategy = ResourceUtils.newConcurGreedPriceStrat(
					observeCPMerch, 
					settings.agentGreedPercent, 
					settings.concurrentPricePercent, 
					concurrentPrices
			);
			((ProductNecessityMerchant)observeCPMerch.getSubmerchant())
				.setPerformPriceStrategy(performPriceStrategy);
			agent.setMerchant(observeCPMerch);
			agent.setWalkStrategy(auditStrat);
			agents[i] = agent;
		}
		return agents;
	}
}
